package com.yxh.www.crawler.util;

import com.xuxueli.crawler.XxlCrawler;
import com.xuxueli.crawler.loader.PageLoader;
import com.xuxueli.crawler.loader.strategy.JsoupPageLoader;
import com.xuxueli.crawler.parser.PageParser;
import com.xuxueli.crawler.proxy.ProxyMaker;
import com.xuxueli.crawler.rundata.RunData;
import com.xuxueli.crawler.rundata.strategy.LocalRunData;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 爬虫生成工器
 * </p>
 *
 * @author yangxiaohui
 * @since 2020/5/15
 */
@Slf4j
public class CrawlerBuilder {
    /**
     * 开启线程数
     */
    private int threadCount = 1;
    /**
     * 是否允许扩散整站爬取
     */
    private boolean allowSpread = false;
    /**
     * 是否同步执行
     */
    private boolean sync = true;
    /**
     * 网站 UA 集合 轮询选中
     */
    private String[] userAgents;
    /**
     * 页面加载器
     */
    private PageLoader pageLoader = new JsoupPageLoader();
    /**
     * 页面解析器
     */
    private PageParser<Object> pageParser;
    /**
     * 代理池
     */
    private ProxyMaker proxyMaker;

    /**
     * 失败重试次数
     */
    private int failRetryCount = 3;
    /**
     * 请求超时时间
     */
    private int timeoutMillis = 60000;
    /**
     * 请求之间间隔时间
     */
    private int pauseMillis = 0;

    /**
     * 请求Cookie参数
     */
    private Map<String, String> cookieMap;
    /**
     * 请求参数
     */
    private String referrer;
    /**
     * 请求参数
     */
    private Map<String, String> paramMap;
    /**
     * 请求头
     */
    private Map<String, String> headerMap;
    /**
     * 白名单
     */
    private String[] whiteUrlRegexs;
    /**
     * 任务配置
     */
    private volatile RunData runData = new LocalRunData();
    /**
     * 爬取地址列表
     */
    private String[] urls;
    /**
     * 爬虫
     */
    private XxlCrawler xxlCrawler;

    public CrawlerBuilder start(PageParser<Object> pageParser) {
        this.pageParser = pageParser;
        this.xxlCrawler = new XxlCrawler.Builder()
                .setUrls(this.urls)
                .setWhiteUrlRegexs(this.whiteUrlRegexs)
                .setThreadCount(this.threadCount)
                .setProxyMaker(proxyMaker)
                .setAllowSpread(this.allowSpread)
                .setPageLoader(this.pageLoader)
                .setFailRetryCount(this.failRetryCount)
                .setTimeoutMillis(this.timeoutMillis)
                .setPauseMillis(this.pauseMillis)
                .setUserAgent(this.userAgents)
                .setCookieMap(this.cookieMap)
                .setParamMap(this.paramMap)
                .setHeaderMap(this.headerMap)
                .setReferrer(this.referrer)
                .setPageParser(this.pageParser)
                .build();
        this.xxlCrawler.start(this.sync);
        return this;
    }

    public void stop() {
        this.xxlCrawler.stop();
    }

    public CrawlerBuilder() {
    }

    public CrawlerBuilder(String... urls) {
        this.urls = urls;
    }
    public static CrawlerBuilder builder(){
        return new CrawlerBuilder();
    }
    public CrawlerBuilder setThreadCount(int threadCount) {
        this.threadCount = threadCount;
        return this;
    }

    public CrawlerBuilder setAllowSpread(boolean allowSpread) {
        this.allowSpread = allowSpread;
        return this;
    }

    public CrawlerBuilder setSync(boolean sync) {
        this.sync = sync;
        return this;
    }

    public CrawlerBuilder setUserAgents(String... userAgents) {
        this.userAgents = userAgents;
        return this;
    }

    public CrawlerBuilder setPageLoader(PageLoader pageLoader) {
        this.pageLoader = pageLoader;
        return this;
    }

    public CrawlerBuilder setPageParser(PageParser<Object> pageParser) {
        this.pageParser = pageParser;
        return this;
    }

    public CrawlerBuilder setUrls(String... urls) {
        this.urls = urls;
        return this;
    }

    public CrawlerBuilder setFailRetryCount(int failRetryCount) {
        this.failRetryCount = failRetryCount;
        return this;
    }

    public CrawlerBuilder setTimeoutMillis(int timeoutMillis) {
        this.timeoutMillis = timeoutMillis;
        return this;
    }

    public CrawlerBuilder setPauseMillis(int pauseMillis) {
        this.pauseMillis = pauseMillis;
        return this;
    }

    public CrawlerBuilder setCookieMap(Map<String, String> cookieMap) {
        this.cookieMap = cookieMap;
        return this;
    }

    public CrawlerBuilder setReferrer(String referrer) {
        this.referrer = referrer;
        return this;
    }

    public CrawlerBuilder setParamMap(Map<String, String> paramMap) {
        this.paramMap = paramMap;
        return this;
    }

    public CrawlerBuilder setHeaderMap(Map<String, String> headerMap) {
        this.headerMap = headerMap;
        return this;
    }

    public CrawlerBuilder setWhiteUrlRegexs(String... whiteUrlRegexs) {
        this.whiteUrlRegexs = whiteUrlRegexs;
        return this;
    }

    public CrawlerBuilder setRunData(RunData runData) {
        this.runData = runData;
        return this;
    }

    public CrawlerBuilder setProxyMaker(ProxyMaker proxyMaker) {
        this.proxyMaker = proxyMaker;
        return this;
    }
}
